package com.flower.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.flower.domain.entity.*;
import com.flower.mapper.*;
import com.flower.service.ShopStatsService;
import com.flower.utils.UserContext;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商铺数据统计服务实现类
 */
@Service
@RequiredArgsConstructor
public class ShopStatsServiceImpl implements ShopStatsService {

    private final OrderMapper orderMapper;
    private final OrderItemMapper orderItemMapper;
    private final ProductMapper productMapper;
    private final CategoryMapper categoryMapper;
    private final ShopMapper shopMapper;

    /**
     * 获取销售趋势数据
     *
     * @param shopId    店铺ID
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param timeUnit  时间单位：day, week, month
     * @return 销售趋势数据
     */
    @Override
    public Map<String, Object> getSalesTrend(Integer shopId, LocalDate startDate, LocalDate endDate, String timeUnit) {
        // 如果未指定店铺ID，则使用当前登录用户的店铺ID
        if (shopId == null) {
            shopId = UserContext.getUserId().intValue();
        }

        // 处理日期范围
        if (startDate == null) {
            startDate = LocalDate.now().minusDays(30);
        }
        if (endDate == null) {
            endDate = LocalDate.now();
        }

        // 获取该日期范围内的所有订单
        LocalDateTime startDateTime = startDate.atStartOfDay();
        LocalDateTime endDateTime = endDate.plusDays(1).atStartOfDay();

        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getShopId, shopId)
                .ge(Order::getCreateTime, startDateTime)
                .lt(Order::getCreateTime, endDateTime)
                .orderByAsc(Order::getCreateTime);

        List<Order> orders = orderMapper.selectList(queryWrapper);

        // 按照时间单位分组计算销售额和订单数
        Map<String, List<Order>> groupedOrders;
        List<String> dateLabels;

        DateTimeFormatter formatter;
        switch (timeUnit) {
            case "week":
                formatter = DateTimeFormatter.ofPattern("yyyy-'W'w");
                groupedOrders = orders.stream()
                        .collect(Collectors.groupingBy(order ->
                                order.getCreateTime().format(formatter)));
                
                // 生成所有周的标签
                dateLabels = generateDateLabels(startDate, endDate, "week");
                break;
            case "month":
                formatter = DateTimeFormatter.ofPattern("yyyy-MM");
                groupedOrders = orders.stream()
                        .collect(Collectors.groupingBy(order ->
                                order.getCreateTime().format(formatter)));
                
                // 生成所有月份的标签
                dateLabels = generateDateLabels(startDate, endDate, "month");
                break;
            default: // day
                formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                groupedOrders = orders.stream()
                        .collect(Collectors.groupingBy(order ->
                                order.getCreateTime().format(formatter)));
                
                // 生成所有日期的标签
                dateLabels = generateDateLabels(startDate, endDate, "day");
        }

        // 计算每个时间单位的销售额和订单数
        List<Integer> salesAmounts = new ArrayList<>();
        List<Integer> orderCounts = new ArrayList<>();

        for (String dateLabel : dateLabels) {
            List<Order> ordersInPeriod = groupedOrders.getOrDefault(dateLabel, Collections.emptyList());
            int salesAmount = ordersInPeriod.stream()
                    .mapToInt(Order::getTotalAmount)
                    .sum();
            int orderCount = ordersInPeriod.size();

            salesAmounts.add(salesAmount);
            orderCounts.add(orderCount);
        }

        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("dates", dateLabels);
        result.put("salesAmounts", salesAmounts);
        result.put("orderCounts", orderCounts);

        return result;
    }

    /**
     * 生成日期标签列表
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @param timeUnit  时间单位
     * @return 日期标签列表
     */
    private List<String> generateDateLabels(LocalDate startDate, LocalDate endDate, String timeUnit) {
        List<String> labels = new ArrayList<>();
        DateTimeFormatter formatter;

        switch (timeUnit) {
            case "week":
                // 调整开始日期为周一
                LocalDate weekStart = startDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
                formatter = DateTimeFormatter.ofPattern("yyyy-'W'w");
                
                while (!weekStart.isAfter(endDate)) {
                    labels.add(weekStart.format(formatter));
                    weekStart = weekStart.plusWeeks(1);
                }
                break;
            case "month":
                // 调整开始日期为月初
                LocalDate monthStart = startDate.withDayOfMonth(1);
                formatter = DateTimeFormatter.ofPattern("yyyy-MM");
                
                while (!monthStart.isAfter(endDate)) {
                    labels.add(monthStart.format(formatter));
                    monthStart = monthStart.plusMonths(1);
                }
                break;
            default: // day
                formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                LocalDate current = startDate;
                
                while (!current.isAfter(endDate)) {
                    labels.add(current.format(formatter));
                    current = current.plusDays(1);
                }
        }

        return labels;
    }

    /**
     * 获取订单状态分布
     *
     * @param shopId 店铺ID
     * @return 订单状态分布数据
     */
    @Override
    public List<Map<String, Object>> getOrderStatusDistribution(Integer shopId) {
        // 如果未指定店铺ID，则使用当前登录用户的店铺ID
        if (shopId == null) {
            shopId = UserContext.getUserId().intValue();
        }

        // 查询所有订单
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Order::getShopId, shopId);
        List<Order> orders = orderMapper.selectList(queryWrapper);

        // 按订单状态分组
        Map<Integer, Long> statusCount = orders.stream()
                .collect(Collectors.groupingBy(Order::getStatus, Collectors.counting()));

        // 订单状态名称映射
        Map<Integer, String> statusNameMap = new HashMap<>();
        statusNameMap.put(0, "待付款");
        statusNameMap.put(1, "待发货");
        statusNameMap.put(2, "待收货");
        statusNameMap.put(3, "已完成");
        statusNameMap.put(4, "已取消");
        statusNameMap.put(5, "已退款");

        // 构建返回结果
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<Integer, String> entry : statusNameMap.entrySet()) {
            Integer status = entry.getKey();
            String name = entry.getValue();
            Long count = statusCount.getOrDefault(status, 0L);

            Map<String, Object> item = new HashMap<>();
            item.put("name", name);
            item.put("value", count);
            result.add(item);
        }

        return result;
    }

    /**
     * 获取热销商品排行
     *
     * @param shopId 店铺ID
     * @param limit  返回数量限制
     * @return 热销商品排行数据
     */
    @Override
    public List<Map<String, Object>> getTopProducts(Integer shopId, Integer limit) {
        // 如果未指定店铺ID，则使用当前登录用户的店铺ID
        if (shopId == null) {
            shopId = UserContext.getUserId().intValue();
        }

        // 查询该店铺的所有订单
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getShopId, shopId)
                .in(Order::getStatus, 1, 2, 3); // 只统计已付款的订单
        List<Order> orders = orderMapper.selectList(orderWrapper);

        if (orders.isEmpty()) {
            return Collections.emptyList();
        }

        // 获取所有订单ID
        List<Integer> orderIds = orders.stream()
                .map(Order::getOrderId)
                .collect(Collectors.toList());

        // 查询所有订单项
        LambdaQueryWrapper<OrderItem> itemWrapper = new LambdaQueryWrapper<>();
        itemWrapper.in(OrderItem::getOrderId, orderIds);
        List<OrderItem> orderItems = orderItemMapper.selectList(itemWrapper);

        // 按商品ID分组统计销售数量和销售额
        Map<Integer, List<OrderItem>> groupedItems = orderItems.stream()
                .collect(Collectors.groupingBy(OrderItem::getProductId));

        // 计算每个商品的销售总量和销售总额
        List<Map<String, Object>> productStats = new ArrayList<>();
        for (Map.Entry<Integer, List<OrderItem>> entry : groupedItems.entrySet()) {
            Integer productId = entry.getKey();
            List<OrderItem> items = entry.getValue();

            int salesCount = items.stream().mapToInt(OrderItem::getQuantity).sum();
            int salesAmount = items.stream().mapToInt(item -> item.getPrice() * item.getQuantity()).sum();

            // 获取商品信息
            Product product = productMapper.selectById(productId);
            if (product != null) {
                Map<String, Object> stat = new HashMap<>();
                stat.put("productId", productId);
                stat.put("productName", product.getProductName());
                stat.put("productImg", product.getImage());
                stat.put("salesCount", salesCount);
                stat.put("salesAmount", salesAmount);
                productStats.add(stat);
            }
        }

        // 按销售数量降序排序并限制返回数量
        return productStats.stream()
                .sorted((a, b) -> Integer.compare((Integer) b.get("salesCount"), (Integer) a.get("salesCount")))
                .limit(limit)
                .collect(Collectors.toList());
    }

    /**
     * 获取商品分类销售分布
     *
     * @param shopId 店铺ID
     * @return 商品分类销售分布数据
     */
    @Override
    public List<Map<String, Object>> getCategoryDistribution(Integer shopId) {
        // 如果未指定店铺ID，则使用当前登录用户的店铺ID
        if (shopId == null) {
            shopId = UserContext.getUserId().intValue();
        }

        // 查询该店铺的所有订单
        LambdaQueryWrapper<Order> orderWrapper = new LambdaQueryWrapper<>();
        orderWrapper.eq(Order::getShopId, shopId)
                .in(Order::getStatus, 1, 2, 3); // 只统计已付款的订单
        List<Order> orders = orderMapper.selectList(orderWrapper);

        if (orders.isEmpty()) {
            return Collections.emptyList();
        }

        // 获取所有订单ID
        List<Integer> orderIds = orders.stream()
                .map(Order::getOrderId)
                .collect(Collectors.toList());

        // 查询所有订单项
        LambdaQueryWrapper<OrderItem> itemWrapper = new LambdaQueryWrapper<>();
        itemWrapper.in(OrderItem::getOrderId, orderIds);
        List<OrderItem> orderItems = orderItemMapper.selectList(itemWrapper);

        // 获取所有涉及到的商品ID
        List<Integer> productIds = orderItems.stream()
                .map(OrderItem::getProductId)
                .distinct()
                .collect(Collectors.toList());

        // 查询所有相关商品
        Map<Integer, Product> productMap = new HashMap<>();
        if (!productIds.isEmpty()) {
            LambdaQueryWrapper<Product> productWrapper = new LambdaQueryWrapper<>();
            productWrapper.in(Product::getProductId, productIds);
            List<Product> products = productMapper.selectList(productWrapper);
            productMap = products.stream()
                    .collect(Collectors.toMap(Product::getProductId, p -> p));
        }

        // 获取所有分类ID
        Set<Integer> categoryIds = productMap.values().stream()
                .map(Product::getCategoryId)
                .collect(Collectors.toSet());

        // 查询所有相关分类
        Map<Integer, Category> categoryMap = new HashMap<>();
        if (!categoryIds.isEmpty()) {
            LambdaQueryWrapper<Category> categoryWrapper = new LambdaQueryWrapper<>();
            categoryWrapper.in(Category::getCategoryId, categoryIds);
            List<Category> categories = categoryMapper.selectList(categoryWrapper);
            categoryMap = categories.stream()
                    .collect(Collectors.toMap(Category::getCategoryId, c -> c));
        }

        // 计算每个分类的销售额
        Map<Integer, Integer> categorySales = new HashMap<>();
        for (OrderItem item : orderItems) {
            Product product = productMap.get(item.getProductId());
            if (product != null) {
                Integer categoryId = product.getCategoryId();
                int amount = item.getPrice() * item.getQuantity();
                categorySales.put(categoryId, categorySales.getOrDefault(categoryId, 0) + amount);
            }
        }

        // 构建返回结果
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : categorySales.entrySet()) {
            Integer categoryId = entry.getKey();
            Integer salesAmount = entry.getValue();
            Category category = categoryMap.get(categoryId);

            if (category != null) {
                Map<String, Object> item = new HashMap<>();
                item.put("categoryId", categoryId);
                item.put("categoryName", category.getCategoryName());
                item.put("salesAmount", salesAmount);
                result.add(item);
            }
        }

        // 按销售额降序排序
        result.sort((a, b) -> Integer.compare((Integer) b.get("salesAmount"), (Integer) a.get("salesAmount")));

        return result;
    }
} 